package com.bestcem.xm.user.grpc.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.ObjectId;
import com.bestcem.bp.xm.user.grpc.v1.services.GroupNode;
import com.bestcem.bp.xm.user.grpc.v1.services.*;
import com.bestcem.xm.common.core.constant.RegTypes;
import com.bestcem.xm.common.core.domain.web.RpcStatusResult;
import com.bestcem.xm.common.core.domain.web.ServiceResult;
import com.bestcem.xm.common.core.enums.ErrorCodeEnum;
import com.bestcem.xm.common.core.enums.ResourceErrorCodeEnum;
import com.bestcem.xm.common.core.exception.GrpcCallFailedException;
import com.bestcem.xm.common.core.uitls.GRpcUtil;
import com.bestcem.xm.user.constant.CommonConstant;
import com.bestcem.xm.user.enums.UserGroupStatusEnum;
import com.bestcem.xm.user.grpc.service.converter.CommonConverter;
import com.bestcem.xm.user.grpc.service.converter.UserGroupConverter;
import com.bestcem.xm.user.grpc.service.converter.UserGroupLevelConverter;
import com.bestcem.xm.user.grpc.service.param.*;
import com.bestcem.xm.user.grpc.v1.enums.GroupTaskStatusEnum;
import com.bestcem.xm.user.service.*;
import com.bestcem.xm.user.service.dto.PageResponseDTO;
import com.bestcem.xm.user.service.dto.group.*;
import com.bestcem.xm.user.util.business.GroupLevelUtil;
import com.bestcem.xm.user.util.business.GroupLockUtil;
import com.google.common.collect.Lists;
import io.grpc.stub.StreamObserver;
import lombok.extern.slf4j.Slf4j;
import net.devh.boot.grpc.server.service.GrpcService;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;

import javax.annotation.Resource;
import javax.validation.ConstraintViolation;
import java.util.*;
import java.util.stream.Collectors;

;

/**
 * 用户中心组织层级相关服务
 *
 * @author qiongyu.cui <qiongyu.cui@idiaoyan.com>
 * @date 2022/1/19 10:42
 */
@Slf4j
@GrpcService
public class UserGroupGrpcService extends UserGroupServiceGrpc.UserGroupServiceImplBase {
    /**
     * 组织相关服务
     */
    @Resource
    private UserGroupService userGroupService;

    @Resource
    private GroupLockUtil groupLockUtil;

    /**
     * 层级相关服务
     */
    @Resource
    private UserGroupLevelService userGroupLevelService;

    /**
     * 用户组织关联关系服务
     */
    @Resource
    private UserUserGroupService userUserGroupService;

    @Resource
    private UserGroupBusinessService userGroupBusinessService;

    @Resource
    private UserGroupImportRecordService userGroupImportRecordService;

    /**
     * 根据用户组id或者【公司id和组编码】查询用户组信息
     *
     * @param request          请求参数
     * @param responseObserver 响应对象
     * @author yanjishuo <jishuo.yan@idiaoyan.cn>
     * @date 2022/01/24 10:30
     */
    @Override
    public void getGroup(GetGroupRequest request, StreamObserver<GetGroupResponse> responseObserver) {
        GetGroupResponse.Builder builder = GetGroupResponse.newBuilder();
        String groupId = request.getId();
        String orgId = request.getOrgId();
        String groupCode = request.getCode();

        // 查询数据库
        ServiceResult<UserGroupDTO> serviceResult;
        if (StringUtils.isNotBlank(groupId)) {
            //通过用户组id查询用户组信息
            serviceResult = userGroupService.getById(groupId);
        } else {
            //通过公司Id和组编码查询用户组信息
            serviceResult = userGroupService.getByOrgIdAndGroupCode(orgId, groupCode);
        }
        if (serviceResult.isSuccess()) {
            //查询成功
            builder.setStatus(RpcStatusResult.success());
            //将用户组信息转成grpc响应结果
            builder.setGroup(UserGroupConverter.userGroupDtoToGroup(serviceResult.getData()));
        } else {
            //查询失败
            builder.setStatus(RpcStatusResult.error(serviceResult.getMsg()));
        }
        responseObserver.onNext(builder.build());
        responseObserver.onCompleted();
    }

    /**
     * 根据根据user_id获取祖先组织(包含用户所在组织)ids
     *
     * @param request          请求参数
     * @param responseObserver 响应对象
     * @author yanjishuo <jishuo.yan@idiaoyan.cn>
     * @date 2022/02/24 17:30
     */
    @Override
    public void listAncestorGroupIdsByUid(ListAncestorGroupIdsByUidRequest request, StreamObserver<ListAncestorGroupIdsByUidResponse> responseObserver) {
        ListAncestorGroupIdsByUidResponse.Builder builder = ListAncestorGroupIdsByUidResponse.newBuilder();
        //获取用户Id
        String userId = request.getUserId();
        ServiceResult<List<String>> serviceResult = userGroupService.getSelfAndParentIdsOrder(userId);
        if (serviceResult.isSuccess()) {
            //查询成功
            builder.setStatus(RpcStatusResult.success());
            builder.addAllIds(serviceResult.getData());
        } else {
            //查询失败
            builder.setStatus(RpcStatusResult.error(serviceResult.getMsg()));
        }
        responseObserver.onNext(builder.build());
        responseObserver.onCompleted();
    }

    /**
     * 根据用户组id查询当前用户组和所有父用户组基础信息
     *
     * @param request          请求参数
     * @param responseObserver 响应对象
     * @author yanjishuo <jishuo.yan@idiaoyan.cn>
     * @date 2022/01/24 15:30
     */
    @Override
    public void listAncestorStoresById(ListAncestorStoresByIdRequest request, StreamObserver<ListAncestorStoresByIdResponse> responseObserver) {
        ListAncestorStoresByIdResponse.Builder builder = ListAncestorStoresByIdResponse.newBuilder();
        //获取组织ID
        String groupId = request.getGroupId();
        ServiceResult<List<UserGroupDTO>> serviceResult = userGroupService.getSelfAndParents(groupId);
        if (serviceResult.isSuccess()) {
            //查询成功
            builder.setStatus(RpcStatusResult.success());
            builder.addAllStores(UserGroupConverter.userGroupDtosToGroupBases(serviceResult.getData()));
        } else {
            //查询失败
            builder.setStatus(RpcStatusResult.error(serviceResult.getMsg()));
        }
        responseObserver.onNext(builder.build());
        responseObserver.onCompleted();
    }

    /**
     * 搜索用户组关联信息列表
     *
     * @param request          请求参数
     * @param responseObserver 响应对象
     * @author yanjishuo <jishuo.yan@idiaoyan.cn>
     * @date 2022/01/25 11:00
     */
    @Override
    public void listUserGroups(ListUserGroupsRequest request, StreamObserver<ListUserGroupsResponse> responseObserver) {
        ListUserGroupsResponse.Builder builder = ListUserGroupsResponse.newBuilder();
        PageParam pageParam = new PageParam(request.getPage().getPage(), request.getPage().getSize());

        UserUserGroupDTO userUserGroupDTO = new UserUserGroupDTO();
        userUserGroupDTO.setUserGroupId(request.getId());
        userUserGroupDTO.setGroupId(request.getGroupId());
        userUserGroupDTO.setUserId(request.getUserId());
        userUserGroupDTO.setRootGroupId(request.getRootGroupId());

        ServiceResult<PageResponseDTO<UserUserGroupDTO>> serviceResult = userUserGroupService.getUserUserGroupList(userUserGroupDTO, pageParam.getPage(), pageParam.getSize());
        //返回数据
        if (serviceResult.isSuccess()) {
            //查询成功
            builder.setStatus(RpcStatusResult.success());
            builder.setTotal(serviceResult.getData().getTotal().intValue());
            builder.addAllGroups(UserGroupConverter.userGroupDtosToUserRelateGroups(serviceResult.getData().getRows()));
        } else {
            //查询失败
            builder.setStatus(RpcStatusResult.error(serviceResult.getMsg()));
        }
        responseObserver.onNext(builder.build());
        responseObserver.onCompleted();
    }

    /**
     * 根据user_id获取用户组id列表
     *
     * @param request          请求参数
     * @param responseObserver 响应对象
     * @author yanjishuo <jishuo.yan@idiaoyan.cn>
     * @date 2022/01/24 11:20
     */
    @Override
    public void listGroupIdsByUid(ListGroupIdsByUidRequest request, StreamObserver<ListGroupIdsByUidResponse> responseObserver) {
        ListGroupIdsByUidResponse.Builder builder = ListGroupIdsByUidResponse.newBuilder();
        //获取组织ID
        String userId = request.getUserId();
        ServiceResult<HashSet<String>> serviceResult = userGroupService.getGroupIdsByUserId(userId);
        if (serviceResult.isSuccess()) {
            //查询成功
            builder.setStatus(RpcStatusResult.success());
            builder.addAllGroupIds(serviceResult.getData());
        } else {
            //查询失败
            builder.setStatus(RpcStatusResult.error(serviceResult.getMsg()));
        }
        responseObserver.onNext(builder.build());
        responseObserver.onCompleted();
    }

    /**
     * 通过根组织id获取组织树的版本号
     *
     * @param request          请求参数
     * @param responseObserver 响应对象
     * @author yanjishuo <jishuo.yan@idiaoyan.cn>
     * @date 2022/01/25 10:20
     */
    @Override
    public void getGroupVerByRootGroupId(GetGroupVerByRootGroupIdRequest request, StreamObserver<GetGroupVerByRootGroupIdResponse> responseObserver) {
        GetGroupVerByRootGroupIdResponse.Builder builder = GetGroupVerByRootGroupIdResponse.newBuilder();
        //获取组织ID
        String rootGroupId = request.getRootGroupId();
        ServiceResult<Integer> serviceResult = userGroupService.getGroupTreeVersion(rootGroupId);
        if (serviceResult.isSuccess()) {
            //查询成功
            builder.setStatus(RpcStatusResult.success());
            builder.setVersion(serviceResult.getData());
        } else {
            //查询失败
            builder.setStatus(RpcStatusResult.error(serviceResult.getMsg()));
        }
        responseObserver.onNext(builder.build());
        responseObserver.onCompleted();
    }

    /**
     * 根据org_id获取该公司下有效的门店Id与门店名称的映射关系
     *
     * @param request          请求参数
     * @param responseObserver 响应对象
     * @author panyun <yun.pan@idiaoyan.com>
     * @date 2022/1/19 19:08
     */
    @Override
    public void listStoreIdNames(ListStoreIdNamesRequest request, StreamObserver<ListStoreIdNamesResponse> responseObserver) {
        ListStoreIdNamesResponse.Builder builder = ListStoreIdNamesResponse.newBuilder();

        //获取该租户下对应的门店
        String orgId = request.getOrgId();
        PageParam pageParam = new PageParam(request.getPage().getPage(), request.getPage().getSize());

        // 获取门店对应的层级id
        ServiceResult<String> storeLevelId = userGroupLevelService.getStoreLevelId(orgId);
        if (!storeLevelId.isSuccess()) {
            log.error("[listStoreIdNames] orgId = {}, storeLevelId = {}", orgId, storeLevelId);
            builder.setStatus(RpcStatusResult.error(storeLevelId.getMsg()));
            responseObserver.onNext(builder.build());
            responseObserver.onCompleted();
            return;
        }

        // 分页查询指定层级组织列表
        GroupListRequestDto groupListRequestDto = new GroupListRequestDto();
        groupListRequestDto.setOrgId(orgId);
        groupListRequestDto.setGroupLevelId(storeLevelId.getData());
        List<Integer> statuses = Lists.newArrayList(UserGroupStatusEnum.ACTIVATED.getStatus());
        groupListRequestDto.setStatuses(statuses);
        ServiceResult<PageResponseDTO<UserGroupDTO>> serviceResult = userGroupService.listPage(groupListRequestDto,
                pageParam.getSize(), pageParam.getPage());
        // 返回数据
        if (serviceResult.isSuccess()) {
            PageResponseDTO<UserGroupDTO> data = serviceResult.getData();
            List<StoreIdName> idNameList = UserGroupConverter.userDtoToStoreIdName(data.getRows());
            builder.setStatus(RpcStatusResult.success());
            builder.setTotal(Objects.isNull(data.getTotal()) ? 0 : data.getTotal().intValue());
            builder.addAllStores(idNameList);
        } else {
            String errMsg = serviceResult.getMsg();
            errMsg = String.format(CommonConstant.ERROR_MSG_FORMATTER, ErrorCodeEnum.SYSTEM_ERROR.getMsg(), errMsg);
            log.error("[listStoreIdNames] orgId = {}, errMsg = {}", orgId, errMsg);
            builder.setStatus(RpcStatusResult.error(errMsg));
        }
        responseObserver.onNext(builder.build());
        responseObserver.onCompleted();
    }

    /**
     * 返回指定的两个公司层级名称相同的id对
     *
     * @param request          请求参数
     * @param responseObserver 响应对象
     * @author wangyunyun <yunyun.wang@idiaoyan.com>
     * @date 2022/1/21 10:30
     */
    @Override
    public void listSampleGroupLevelIds(ListSampleGroupLevelIdsRequest request, StreamObserver<ListSampleGroupLevelIdsResponse> responseObserver) {
        // 返回指定的两个公司层级名称相同的id对
        ServiceResult<List<IdRelationDTO>> serviceResult = userGroupBusinessService
                .listSampleGroupLevelIds(request.getSrcOrgId(), request.getDstOrgId());

        ListSampleGroupLevelIdsResponse.Builder builder = ListSampleGroupLevelIdsResponse.newBuilder();
        if (serviceResult.isSuccess()) {
            // 查询成功
            builder.setStatus(RpcStatusResult.success());
            builder.addAllIdRelations(CommonConverter.idRelationDtosGrpcs(serviceResult.getData()));
            responseObserver.onNext(builder.build());
            responseObserver.onCompleted();
        } else {
            // 查询失败
            builder.setStatus(RpcStatusResult.error(serviceResult.getMsg()));
            responseObserver.onNext(builder.build());
            responseObserver.onCompleted();
        }
    }

    /**
     * 返回指定的两个公司组织名称和seq相同的id对
     *
     * @param request          请求参数
     * @param responseObserver 响应对象
     * @author wangyunyun <yunyun.wang@idiaoyan.com>
     * @date 2022/1/21 14:30
     */
    @Override
    public void listSampleGroupIds(ListSampleGroupIdsRequest request, StreamObserver<ListSampleGroupIdsResponse> responseObserver) {
        // 参数校验
        ServiceResult<List<IdRelationDTO>> serviceResult = userGroupBusinessService
                .listSampleGroupIds(request.getSrcOrgId(), request.getDstOrgId());

        ListSampleGroupIdsResponse.Builder builder = ListSampleGroupIdsResponse.newBuilder();
        if (serviceResult.isSuccess()) {
            // 查询成功
            builder.setStatus(RpcStatusResult.success());
            builder.addAllIdRelations(CommonConverter.idRelationDtosGrpcs(serviceResult.getData()));
            responseObserver.onNext(builder.build());
            responseObserver.onCompleted();
        } else {
            // 查询失败
            builder.setStatus(RpcStatusResult.error(serviceResult.getMsg()));
            responseObserver.onNext(builder.build());
            responseObserver.onCompleted();
        }
    }

    /**
     * 根据用户组id列表获取指定层级上的子用户组列表
     *
     * @param request          请求参数
     * @param responseObserver 响应结果
     * @return void
     * @author cuiqiongyu <qiongyu.cui@idiaoyan.cn>
     * @date 2022/01/21 13:47
     */
    @Override
    public void listSubRelatedGroups(ListSubRelatedGroupsRequest request, StreamObserver<ListSubRelatedGroupsResponse> responseObserver) {
        // 获取返回对象的构造器
        ListSubRelatedGroupsResponse.Builder builder = ListSubRelatedGroupsResponse.newBuilder();

        // 根据用户组id列表分页获取指定层级上的子用户列表
        ServiceResult<PageResponseDTO<UserGroupDTO>> result = userGroupBusinessService.pageSubRelateGroups(request.getGroupLevelId(),
                request.getGroupIdsList(), request.getPage().getPage(), request.getPage().getSize());
        if (!result.isSuccess()) {
            builder.setStatus(RpcStatusResult.error(result.getMsg()));
        } else {
            builder.setStatus(RpcStatusResult.success());
            if (null == result.getData().getTotal()) {
                builder.setTotal(0);
            } else {
                builder.setTotal(result.getData().getTotal().intValue());
            }
            List<GroupBase> groupBases = UserGroupConverter.userGroupDtosToGroupBases(result.getData().getRows());
            builder.addAllGroups(groupBases);
        }

        responseObserver.onNext(builder.build());
        responseObserver.onCompleted();
    }

    /**
     * 获取当前用户组所在层级及所有子层级的列表
     *
     * @param request          请求参数
     * @param responseObserver 响应结果
     * @return void
     * @author cuiqiongyu <qiongyu.cui@idiaoyan.cn>
     * @date 2022/01/21 13:47
     */
    @Override
    public void listSubGroupLevelsByGroupId(ListSubGroupLevelsByGroupIdRequest request,
                                            StreamObserver<ListSubGroupLevelsByGroupIdResponse> responseObserver) {
        // 获取返回对象的构造器
        ListSubGroupLevelsByGroupIdResponse.Builder builder = ListSubGroupLevelsByGroupIdResponse.newBuilder();

        // 获取当前用户组所在层级及所有子层级的列表
        ServiceResult<UserGroupDTO> userGroup = userGroupService.getById(request.getGroupId());
        if (!userGroup.isSuccess() || null == userGroup.getData()) {
            builder.setStatus(RpcStatusResult.error("组织id无效，未查询到组织信息"));
            responseObserver.onNext(builder.build());
            responseObserver.onCompleted();
            return;
        }

        // 查询当前公司下所有的层级信息
        ServiceResult<List<UserGroupLevelDTO>> listServiceResult = userGroupLevelService.listByOrgId(userGroup.getData().getOrgId());
        if (!listServiceResult.isSuccess() || CollectionUtils.isEmpty(listServiceResult.getData())) {
            builder.setStatus(RpcStatusResult.error("未查询到对应组织下的层级列表信息"));
            responseObserver.onNext(builder.build());
            responseObserver.onCompleted();
            return;
        }
        // 返回数据
        Integer levelNum = listServiceResult.getData().stream().filter(l -> l.getGroupLevelId().equals(userGroup.getData().getGroupLevelId()))
                .map(UserGroupLevelDTO::getLevelNum).findFirst().orElse(0);
        // 过滤加排序
        List<UserGroupLevelDTO> collect = listServiceResult.getData().stream()
                .filter(l -> l.getLevelNum().compareTo(levelNum) >= 0)
                .sorted(Comparator.comparing(UserGroupLevelDTO::getLevelNum))
                .collect(Collectors.toList());
        List<GroupLevel> groupLevels = UserGroupConverter.userGroupLevelDtosToGroupLevels(collect);
        builder.addAllLevels(groupLevels);

        builder.setStatus(RpcStatusResult.success());
        responseObserver.onNext(builder.build());
        responseObserver.onCompleted();
    }

    /**
     * 更新用户关联组列表信息
     *
     * @param request          请求参数
     * @param responseObserver 响应结果
     * @return void
     * @author cuiqiongyu <qiongyu.cui@idiaoyan.cn>
     * @date 2022/01/21 13:48
     */
    @Override
    public void updateUserGroup(UpdateUserGroupRequest request, StreamObserver<UpdateUserGroupResponse> responseObserver) {
        // 获取返回对象的构造器
        UpdateUserGroupResponse.Builder builder = UpdateUserGroupResponse.newBuilder();

        // 更新用户关联组列表信息
        ServiceResult<List<String>> result = userUserGroupService.updateUserGroups(request.getOrgId(),
                request.getUserId(), request.getGroupIdsList());
        if (!result.isSuccess()) {
            builder.setStatus(RpcStatusResult.error(result.getMsg()));
        } else {
            builder.setStatus(RpcStatusResult.success());
            builder.addAllIds(result.getData());
        }

        responseObserver.onNext(builder.build());
        responseObserver.onCompleted();
    }

    /**
     * 开放平台获取用户组织层级信息
     *
     * @param request          请求参数
     * @param responseObserver 响应结果
     * @return void
     * @author cuiqiongyu <qiongyu.cui@idiaoyan.cn>
     * @date 2022/01/21 13:48
     */
    @Override
    public void getOpenGroupTree(GetOpenGroupTreeRequest request, StreamObserver<GetOpenGroupTreeResponse> responseObserver) {
        // 获取返回对象的构造器
        GetOpenGroupTreeResponse.Builder builder = GetOpenGroupTreeResponse.newBuilder();

        // 获取入参信息
        String orgId = request.getOrgId();
        PageParam pageParam = new PageParam(request.getPage().getPage(), request.getPage().getSize());
        // 查询当前租户下所有的层级信息
        ServiceResult<List<UserGroupLevelDTO>> result1 = userGroupLevelService.listByOrgId(orgId);
        if (!result1.isSuccess()) {
            builder.setStatus(RpcStatusResult.error(result1.getMsg()));
            responseObserver.onNext(builder.build());
            responseObserver.onCompleted();
        }

        // 根据租户id和分页信息查询所有状态为有效的组织列表
        GroupListRequestDto param = new GroupListRequestDto();
        param.setOrgId(orgId);
        List<Integer> statuses = new ArrayList<>();
        statuses.add(UserGroupStatusEnum.ACTIVATED.getStatus());
        param.setStatuses(statuses);
        ServiceResult<PageResponseDTO<UserGroupDTO>> result2 = userGroupService.listPage(param, pageParam.getSize(), pageParam.getPage());
        if (!result2.isSuccess()) {
            builder.setStatus(RpcStatusResult.error(result2.getMsg()));
            responseObserver.onNext(builder.build());
            responseObserver.onCompleted();
        }
        PageResponseDTO<UserGroupDTO> data = result2.getData();
        builder.addAllLevels(UserGroupLevelConverter.dtosToOpenGroupLevelInfo(result1.getData()));
        builder.addAllGroups(UserGroupConverter.dtosToOpenGroupInfo(data.getRows()));
        builder.setTotal(Objects.isNull(data.getTotal()) ? 0 : data.getTotal().intValue());
        responseObserver.onNext(builder.build());
        responseObserver.onCompleted();
    }

    /**
     * 搜索用户组列表
     *
     * @param
     * @return
     * @author Linked <zhijian.lin@idiaoyan.com>
     * @date 2022/1/24 14:39
     */
    @Override
    public void listGroups(ListGroupsRequest request, StreamObserver<ListGroupsResponse> responseObserver) {
        ListGroupsResponse.Builder builder = ListGroupsResponse.newBuilder();

        UserGroupListParam param = UserGroupConverter.requestToUserGroupListParam(request);
        PageResponseDTO<UserGroupDTO> page = userGroupService.listUserGroups(param);
        List<Group> groupList = UserGroupConverter.userGroupDTOToResponse(page.getRows());

        builder.addAllGroups(groupList);
        builder.setTotal(Math.toIntExact(page.getTotal()));
        builder.setStatus(RpcStatusResult.success());

        responseObserver.onNext(builder.build());
        responseObserver.onCompleted();
    }

    /**
     * 根据用户组id列表获取指定层级上关联的用户组信息
     * rpc_mysql/user/server.py:289
     *
     * @param request:
     * @return
     * @author Linked <zhijian.lin@idiaoyan.com>
     * @date 2022/1/25 16:52
     */
    @Override
    public void listRelatedGroups(ListRelatedGroupsRequest request, StreamObserver<ListRelatedGroupsResponse> responseObserver) {

        ListRelatedGroupsResponse.Builder builder = ListRelatedGroupsResponse.newBuilder();
        ListRelateGroupsParam param = UserGroupConverter.requestToListRelateGroupsParam(request);

        if (StringUtils.isBlank(param.getGroupLevelId()) || CollectionUtils.isEmpty(param.getGroupIds())) {
            String errMsg = String.format(CommonConstant.ERROR_MSG_FORMATTER, ErrorCodeEnum.PARAM_ERROR.getMsg(), "参数缺失");
            builder.setStatus(RpcStatusResult.error(errMsg));
            responseObserver.onNext(builder.build());
            responseObserver.onCompleted();
        }
        ListRelateGroupsDTO relateGroupsDTO = userGroupService.listRelateGroups(param);
        List<GroupBase> groupBaseList = UserGroupConverter.userGroupBaseToResponse(relateGroupsDTO.getGroups());
        builder.setTotal(relateGroupsDTO.getTotal());
        builder.addAllGroups(groupBaseList);
        builder.setStatus(RpcStatusResult.success());
        responseObserver.onNext(builder.build());
        responseObserver.onCompleted();
    }

    /**
     * 覆盖更新用户所属组织信息
     *
     * @param request:
     * @return
     * @author Linked <zhijian.lin@idiaoyan.com>
     * @date 2022/1/25 16:52
     */
    @Override
    public void syncUserRelatedGroup(SyncUserRelatedGroupRequest request, StreamObserver<SyncUserRelatedGroupResponse> responseObserver) {
        SyncUserRelatedGroupResponse.Builder builder = SyncUserRelatedGroupResponse.newBuilder();
        SyncUserGroupRelateParam param = UserGroupConverter.userGroupRelateToRequest(request);
        if (StringUtils.isBlank(param.getOrgId())
                || StringUtils.isBlank(param.getUserId())
                || param.getGroupCodes().isEmpty()) {
            String errMsg = String.format(CommonConstant.ERROR_MSG_FORMATTER, ErrorCodeEnum.PARAM_ERROR.getMsg(), "参数缺失");
            builder.setStatus(RpcStatusResult.error(errMsg));
            responseObserver.onNext(builder.build());
            responseObserver.onCompleted();
        }
        Set<String> groupCodes = new HashSet<>(param.getGroupCodes());
        ServiceResult<List<UserGroupDTO>> userGroupList = userGroupService.getByOrgIdAndGroupCodes(param.getOrgId(), groupCodes);
        if (!userGroupList.isSuccess() && CollectionUtils.isEmpty(userGroupList.getData())) {
            builder.setStatus(RpcStatusResult.error("未找到组织"));
            responseObserver.onNext(builder.build());
            responseObserver.onCompleted();
        }
        // 获取组织ids
        List<String> groupIds = userGroupList.getData().stream().map(UserGroupDTO::getGroupId).collect(Collectors.toList());
        // 更新用户关联组织
        ServiceResult<List<String>> listServiceResult = userUserGroupService.updateUserGroups(param.getOrgId(), param.getUserId(), groupIds);
        if (!listServiceResult.isSuccess()) {
            builder.setStatus(RpcStatusResult.error(listServiceResult.getMsg()));
            responseObserver.onNext(builder.build());
            responseObserver.onCompleted();
        }
        builder.addAllIds(listServiceResult.getData());
        builder.setStatus(RpcStatusResult.success());
        responseObserver.onNext(builder.build());
        responseObserver.onCompleted();

    }

    /**
     * 根据组织id列表查询当前组以及所有子组信息
     *
     * @param request:
     * @return
     * @author Linked <zhijian.lin@idiaoyan.com>
     * @date 2022/1/26 16:27
     */
    @Override
    public void listSubGroupsByGroupIds(ListSubGroupsByGroupIdsRequest request, StreamObserver<ListSubGroupsByGroupIdsResponse> responseObserver) {
        ListSubGroupsByGroupIdsResponse.Builder builder = ListSubGroupsByGroupIdsResponse.newBuilder();
        ListSubGroupsByGroupIdsParam param = UserGroupConverter.requestToListSubGroupsByGroupIdsParam(request);
        if (param.getGroupIds().isEmpty() || Objects.isNull(param.getPageParam())) {
            String errMsg = String.format(CommonConstant.ERROR_MSG_FORMATTER, ErrorCodeEnum.PARAM_ERROR.getMsg(), "参数缺失");
            builder.setStatus(RpcStatusResult.error(errMsg));
            responseObserver.onNext(builder.build());
            responseObserver.onCompleted();
        }
        ListSubGroupsDTO subGroupsDTO = userGroupService.getSubGroupsByGroupIds(param);

        List<GroupBase> groupBaseList = UserGroupConverter.groupBaseDTOToGroupBase(subGroupsDTO.getGroups());
        builder.addAllGroups(groupBaseList);
        builder.setTotal(Math.toIntExact(subGroupsDTO.getTotal()));
        builder.setStatus(RpcStatusResult.success());

        responseObserver.onNext(builder.build());
        responseObserver.onCompleted();
    }


    /**
     * 根据用户组根节点id获取该用户组及子用户组的信息
     *
     * @param request          请求参数
     * @param responseObserver 响应对象
     * @return void
     * @author Linked <zhijian.lin@idiaoyan.com>
     * @date 2022/2/28 13:45
     */
    @Override
    public void getGroupTreeByGroupId(GetGroupTreeByGroupIdRequest request, StreamObserver<GetGroupTreeByGroupIdResponse> responseObserver) {
        GetGroupTreeByGroupIdResponse.Builder builder = GetGroupTreeByGroupIdResponse.newBuilder();
        String groupId = request.getGroupId();
        boolean includeInactive = request.getIncludeInactive();
        if (!ObjectId.isValid(groupId)) {
            String errMsg = String.format(CommonConstant.ERROR_MSG_FORMATTER, ErrorCodeEnum.PARAM_ERROR.getMsg(), "用户组id为空或者格式不正确");
            builder.setStatus(RpcStatusResult.error(errMsg));
            responseObserver.onNext(builder.build());
            responseObserver.onCompleted();
        }

        // 限制整棵树的大小
        ServiceResult<Integer> childrenCountById = userGroupService.getSelfAndChildrenCountByGroupId(groupId, includeInactive);
        if (childrenCountById.getData() > CommonConstant.CHILDREN_COUNT) {
            String errMsg = "结果集数量超过限制，请调用listGroupsByOrgIdOrParentId";
            errMsg = String.format(CommonConstant.ERROR_MSG_FORMATTER, ErrorCodeEnum.SYSTEM_ERROR.getMsg(), errMsg);
            builder.setStatus(RpcStatusResult.error(errMsg));
            responseObserver.onNext(builder.build());
            responseObserver.onCompleted();
            return;
        } else if (childrenCountById.getData() == 0) {
            builder.setStatus(RpcStatusResult.success());
            responseObserver.onNext(builder.build());
            responseObserver.onCompleted();
            return;
        }

        // 直接查询出所有的节点树
        ServiceResult<List<UserGroupDTO>> serviceResult = userGroupService.getSelfAndChildrenByGroupId(groupId, includeInactive);
        // 返回数据
        if (serviceResult.isSuccess()) {
            List<UserGroupDTO> userGroupDTOList = serviceResult.getData();
            GroupNode groupNode = UserGroupConverter.groupDtoToGroupNodeTree(userGroupDTOList, groupId);
            if (Objects.nonNull(groupNode)) {
                builder.setTree(groupNode);
            }
            builder.setStatus(RpcStatusResult.success());
        } else {
            String errMsg = serviceResult.getMsg();
            errMsg = String.format(CommonConstant.ERROR_MSG_FORMATTER, ErrorCodeEnum.SYSTEM_ERROR.getMsg(), errMsg);
            builder.setStatus(RpcStatusResult.error(errMsg));
        }
        responseObserver.onNext(builder.build());
        responseObserver.onCompleted();
    }

    /**
     * 支持模糊搜索用户组列表
     *
     * @param request
     * @param responseObserver
     * @return void
     * @author cuiqiongyu <qiongyu.cui@idiaoyan.cn>
     * @date 2022/06/30 13:57
     */
    @Override
    public void searchGroups(SearchGroupsRequest request, StreamObserver<SearchGroupsResponse> responseObserver) {
        SearchGroupsResponse.Builder builder = SearchGroupsResponse.newBuilder();

        // 获取请求参数
        SearchGroupsParam searchGroupsParam = UserGroupConverter.requestToSearchGroupsParam(request);

        // 根据筛选条件灵活获取Group数据
        ServiceResult<PageResponseDTO<UserGroupDTO>> result = userGroupService.searchGroups(searchGroupsParam);
        if (!result.isSuccess()) {
            builder.setStatus(RpcStatusResult.error(result.getMsg()));
        } else {
            List<UserGroupDTO> rows = result.getData().getRows();
            List<Group> groups = new ArrayList<>();
            for (UserGroupDTO userGroupDTO : rows) {
                Group group = UserGroupConverter.userGroupDtoToGroup(userGroupDTO);
                groups.add(group);
            }
            builder.setStatus(RpcStatusResult.success());
            builder.addAllGroups(groups);
            builder.setTotal(Math.toIntExact(result.getData().getTotal()));
            responseObserver.onNext(builder.build());
            responseObserver.onCompleted();
        }
    }

    /**
     * 根据指定用户组id和层级id 分页查询指定层级上的子用户组列表
     *
     * @param request
     * @param responseObserver
     * @return void
     * @author cuiqiongyu <qiongyu.cui@idiaoyan.cn>
     * @date 2022/02/24 11:40
     */
    @Override
    public void listSubGroupsByGroupIdAndLevelId(ListSubGroupsByGroupIdAndLevelIdRequest request,
                                                 StreamObserver<ListSubGroupsByGroupIdAndLevelIdResponse> responseObserver) {
        ListSubGroupsByGroupIdAndLevelIdResponse.Builder builder = ListSubGroupsByGroupIdAndLevelIdResponse.newBuilder();

        // 根据指定用户组id和层级id 分页查询指定层级上的子用户组列表
        ServiceResult<PageResponseDTO<UserGroupDTO>> result = userGroupService.pageChildrenByGroupIdAndLevelId(request.getGroupId(),
                request.getGroupLevelId(), request.getIncludeInactive(), request.getPage().getPage(), request.getPage().getSize());

        if (!result.isSuccess()) {
            builder.setStatus(RpcStatusResult.error(result.getMsg()));
        } else {
            builder.setStatus(RpcStatusResult.success());
            builder.setTotal(result.getData().getTotal().intValue());
            List<GroupBase> groupBases = UserGroupConverter.userGroupDtosToGroupBases(result.getData().getRows());
            builder.addAllGroups(groupBases);
        }

        responseObserver.onNext(builder.build());
        responseObserver.onCompleted();
    }

    /**
     * 根据公司id或父组织id获取公司的用户组列表
     *
     * @param request          请求参数
     * @param responseObserver 响应对象
     * @return void
     * @author panyun <yun.pan@idiaoyan.com>
     * @date 2022/1/23 19:04
     */
    @Override
    public void listGroupsByOrgIdOrParentId(ListGroupsByOrgIdOrParentIdRequest request, StreamObserver<ListGroupsByOrgIdOrParentIdResponse> responseObserver) {
        ListGroupsByOrgIdOrParentIdResponse.Builder builder = ListGroupsByOrgIdOrParentIdResponse.newBuilder();

        //构建参数
        OrgStatusPageParam param = UserGroupConverter.requestToOrgStatsQueryParam(request);

        //参数校验
        List<String> violationMessages = new ArrayList<>();
        if (Objects.isNull(param.getOrgId()) && Objects.isNull(param.getParentGroupId())) {
            violationMessages.add("公司Id和父组织id不能同时为空");
        }
        if (Objects.nonNull(param.getOrgId()) && Objects.nonNull(validateId(param.getOrgId()))) {
            violationMessages.add(validateId(param.getOrgId()));
        }
        if (Objects.nonNull(param.getParentGroupId()) && Objects.nonNull(validateId(param.getParentGroupId()))) {
            violationMessages.add(validateId(param.getParentGroupId()));
        }
        if (CollUtil.isNotEmpty(violationMessages)) {
            String errMsg = String.format(CommonConstant.ERROR_MSG_FORMATTER,
                    ErrorCodeEnum.PARAM_ERROR.getMsg(), violationMessages.get(0));
            builder.setStatus(RpcStatusResult.error(errMsg));

            responseObserver.onNext(builder.build());
            responseObserver.onCompleted();
            return;
        }

        ServiceResult<List<UserGroupDTO>> serviceResult = null;
        ServiceResult<Long> total = null;
        if (StringUtils.isNotBlank(param.getOrgId())) {
            //根据公司id获取公司的用户组列表
            ServiceResult<UserGroupDTO> rootGroupByOrgId = userGroupService.getRootGroupByOrgId(param.getOrgId());
            UserGroupDTO rootGroup = rootGroupByOrgId.getData();
            serviceResult = ServiceResult.success(Objects.nonNull(rootGroup) ? Collections.singletonList(rootGroup) : new ArrayList<>());
            total = userGroupService.userGroupCountByOrgId(param);
        }

        if (Objects.isNull(param.getOrgId()) && StringUtils.isNotBlank(param.getParentGroupId())) {
            //根据父组织id获取下一层级的子用户组列表
            ServiceResult<PageResponseDTO<UserGroupDTO>> result = userGroupService.userGroupListByParentGroupId(param);
            PageResponseDTO<UserGroupDTO> resultData = result.getData();
            serviceResult = ServiceResult.success(Objects.nonNull(resultData.getRows()) ? resultData.getRows() : new ArrayList<>());
            total = ServiceResult.success(resultData.getTotal());
        }

        // 返回数据
        if (serviceResult == null) {
            builder.setStatus(RpcStatusResult.error("查询用户组列表失败"));
            responseObserver.onNext(builder.build());
            responseObserver.onCompleted();
            return;
        }
        if (serviceResult.isSuccess()) {
            ArrayList<Group> groups = new ArrayList<>();
            for (UserGroupDTO groupDTO : serviceResult.getData()) {
                Group group = UserGroupConverter.userGroupDtoToGroup(groupDTO);
                groups.add(group);
            }
            builder.setStatus(RpcStatusResult.success());
            builder.addAllGroups(groups);
            builder.setTotal(total.getData().intValue());
        } else {
            String errMsg = serviceResult.getMsg();
            errMsg = String.format(CommonConstant.ERROR_MSG_FORMATTER, ErrorCodeEnum.SYSTEM_ERROR.getMsg(), errMsg);
            builder.setStatus(RpcStatusResult.error(errMsg));
        }
        responseObserver.onNext(builder.build());
        responseObserver.onCompleted();
    }


    /**
     * 根据公司id获取该公司的根用户组信息
     *
     * @param request          请求信息
     * @param responseObserver 响应内容
     * @return void
     * @author panyun <yun.pan@idiaoyan.com>
     * @date 2022/1/24 15:20
     */
    @Override
    public void getRootGroup(GetRootGroupRequest request, StreamObserver<GetRootGroupResponse> responseObserver) {
        GetRootGroupResponse.Builder builder = GetRootGroupResponse.newBuilder();

        //获取该租户下的根用户组
        String orgId = request.getOrgId();
        ServiceResult<UserGroupDTO> serviceResult = userGroupService.getRootGroupByOrgId(orgId);

        //返回数据
        if (serviceResult.isSuccess() && Objects.nonNull(serviceResult.getData())) {
            Group group = UserGroupConverter.userGroupDtoToGroup(serviceResult.getData());
            builder.setStatus(RpcStatusResult.success());
            builder.setGroup(group);
        } else {
            String errMsg = !serviceResult.isSuccess() ? serviceResult.getMsg() : "未查询到对应的根用户组信息";
            errMsg = String.format(CommonConstant.ERROR_MSG_FORMATTER, ErrorCodeEnum.SYSTEM_ERROR.getMsg(), errMsg);
            builder.setStatus(RpcStatusResult.error(errMsg));
        }
        responseObserver.onNext(builder.build());
        responseObserver.onCompleted();
    }

    /**
     * 根据层级id获取层级信息
     *
     * @param request          请求信息
     * @param responseObserver 响应内容
     * @return void
     * @author panyun <yun.pan@idiaoyan.com>
     * @date 2022/1/25 10:54
     */
    @Override
    public void getGroupLevelById(GetGroupLevelByIdRequest request, StreamObserver<GetGroupLevelByIdResponse> responseObserver) {
        GetGroupLevelByIdResponse.Builder builder = GetGroupLevelByIdResponse.newBuilder();

        //根据层级id获取层级
        String groupLevelId = request.getLevelId();
        ServiceResult<UserGroupLevelDTO> serviceResult = userGroupLevelService.getById(groupLevelId);

        //返回数据
        if (serviceResult.isSuccess()) {
            GroupLevel groupLevel = UserGroupLevelConverter.dtoToGroupLevel(serviceResult.getData());
            builder.setStatus(RpcStatusResult.success())
                    .setLevel(groupLevel);
        } else {
            String errMsg = serviceResult.getMsg();
            errMsg = String.format(CommonConstant.ERROR_MSG_FORMATTER, ErrorCodeEnum.SYSTEM_ERROR.getMsg(), errMsg);
            builder.setStatus(RpcStatusResult.error(errMsg));
        }
        responseObserver.onNext(builder.build());
        responseObserver.onCompleted();
    }


    /**
     * 检查某公司的用户组编码是否可用
     *
     * @param request          请求信息
     * @param responseObserver 响应内容
     * @return void
     * @author panyun <yun.pan@idiaoyan.com>
     * @date 2022/1/25 11:26
     */
    @Override
    public void checkUserGroupCode(CheckUserGroupCodeRequest request, StreamObserver<CheckUserGroupCodeResponse> responseObserver) {
        CheckUserGroupCodeResponse.Builder builder = CheckUserGroupCodeResponse.newBuilder();

        //验证用户组编码
        String groupCode = request.getGroupCode();
        String orgId = request.getOrgId();
        ServiceResult<Boolean> serviceResult = userGroupService.checkGroupCode(groupCode, orgId);

        //返回数据
        if (serviceResult.isSuccess()) {
            builder.setStatus(RpcStatusResult.success())
                    .setValid(serviceResult.getData());
        } else {
            String errMsg = serviceResult.getMsg();
            errMsg = String.format(CommonConstant.ERROR_MSG_FORMATTER, ErrorCodeEnum.SYSTEM_ERROR.getMsg(), errMsg);
            builder.setStatus(RpcStatusResult.error(errMsg));
        }
        responseObserver.onNext(builder.build());
        responseObserver.onCompleted();
    }

    /**
     * 获取指定组下的用户id列表
     *
     * @param request          请求信息
     * @param responseObserver 响应内容
     * @return void
     * @author panyun <yun.pan@idiaoyan.com>
     * @date 2022/1/25 11:37
     */
    @Override
    public void listUserIdsByGroupIds(ListUserIdsByGroupIdsRequest request, StreamObserver<ListUserIdsByGroupIdsResponse> responseObserver) {
        ListUserIdsByGroupIdsResponse.Builder builder = ListUserIdsByGroupIdsResponse.newBuilder();

        boolean includeChildren = request.hasIncludeChildren() ? request.getIncludeChildren() : Boolean.FALSE;
        GroupIdsPageParam param = UserGroupConverter.requestToGroupIdsPageParam(request.getPage(), request.getGroupIdsList(),
                includeChildren);

        //参数校验
        Set<ConstraintViolation<Object>> violations = GRpcUtil.validateParam(param);
        if (!CollectionUtils.isEmpty(violations)) {
            ConstraintViolation<Object> violation = violations.iterator().next();
            String errMsg = String.format(CommonConstant.ERROR_MSG_FORMATTER,
                    ErrorCodeEnum.PARAM_ERROR.getMsg(), violation.getMessage());
            builder.setStatus(RpcStatusResult.error(errMsg));

            responseObserver.onNext(builder.build());
            responseObserver.onCompleted();
            return;
        }

        if (includeChildren) {
            //获取指定用户组以及所有子用户组
            ServiceResult<List<UserGroupDTO>> result = userGroupService.getChildrenByGroupIds(request.getGroupIdsList());
            List<String> idList = result.getData().stream().map(UserGroupDTO::getGroupId).collect(Collectors.toList());
            param.setGroupIds(idList);
        }

        //获取指定用户组下的用户id列表
        ServiceResult<List<String>> serviceResult = userUserGroupService.listUserFromGroups(param);
        List<String> userIds = serviceResult.getData();

        // 获取数据总条数
        ServiceResult<Integer> countResult = userUserGroupService.getUserCountByGroupIds(param.getGroupIds());

        //返回数据
        if (serviceResult.isSuccess() && countResult.isSuccess()) {
            builder.setStatus(RpcStatusResult.success())
                    .setTotal(countResult.getData())
                    .addAllIds(userIds);
        } else {
            String errMsg = serviceResult.getMsg();
            errMsg = String.format(CommonConstant.ERROR_MSG_FORMATTER, ErrorCodeEnum.SYSTEM_ERROR.getMsg(), errMsg);
            builder.setStatus(RpcStatusResult.error(errMsg));
        }
        responseObserver.onNext(builder.build());
        responseObserver.onCompleted();
    }

    /**
     * 根据组织code获取组织列表
     *
     * @param request          请求信息
     * @param responseObserver 响应内容
     * @return void
     * @author panyun <yun.pan@idiaoyan.com>
     * @date 2022/5/17 12:45
     */
    @Override
    public void listGroupsByCodes(ListGroupsByCodesRequest request, StreamObserver<ListGroupsByCodesResponse> responseObserver) {
        ListGroupsByCodesResponse.Builder builder = ListGroupsByCodesResponse.newBuilder();

        String orgId = request.getOrgId();
        List<String> groupCodesList = request.getCodesList();
        List<Integer> statusList = new ArrayList<>();
        for (com.bestcem.xm.user.grpc.v1.enums.GroupStatusEnum.GroupStatus status : request.getStatusesList()) {
            statusList.add(status.getNumber());
        }
        if (!ObjectId.isValid(orgId)) {
            builder.setStatus(RpcStatusResult.error("orgId格式不正确"));
            responseObserver.onNext(builder.build());
            responseObserver.onCompleted();
            return;
        }

        ServiceResult<List<UserGroupDTO>> result = userGroupService.listGroupsByCodes(orgId, groupCodesList, statusList);

        List<Group> groups = new ArrayList<>();
        for (UserGroupDTO userGroupDTO : result.getData()) {
            Group group = UserGroupConverter.userGroupDtoToGroup(userGroupDTO);
            groups.add(group);
        }
        builder.setStatus(RpcStatusResult.success());
        builder.addAllGroups(groups);
        responseObserver.onNext(builder.build());
        responseObserver.onCompleted();
    }

    /**
     * 根据用户id，查询用户所在组
     *
     * @param request:
     * @param responseObserver:
     * @return
     * @author Linked <zhijian.lin@idiaoyan.com>
     * @date 2022/2/14 18:51
     */
    @Override
    public void listGroupsByUid(ListGroupsByUidRequest request, StreamObserver<ListGroupsByUidResponse> responseObserver) {
        ListGroupsByUidResponse.Builder builder = ListGroupsByUidResponse.newBuilder();
        UserGroupListByUserIdParam param = UserGroupConverter.requestToGroupListByUserId(request);
        List<Group> groups = new ArrayList<>();
        String userId = request.getUserId();
        if (StringUtils.isBlank(userId)) {
            String errMsg = String.format(CommonConstant.ERROR_MSG_FORMATTER, ErrorCodeEnum.PARAM_ERROR.getMsg(), "参数缺失");
            builder.setStatus(RpcStatusResult.error(errMsg));
            responseObserver.onNext(builder.build());
            responseObserver.onCompleted();
        }
        PageResponseDTO<UserGroupDTO> result = userGroupService.getGroupListByUserId(param);
        for (UserGroupDTO userGroupDTO : result.getRows()) {
            Group group = UserGroupConverter.userGroupDtoToGroup(userGroupDTO);
            groups.add(group);
        }
        builder.setTotal(Math.toIntExact(result.getTotal()));
        builder.addAllGroups(groups);
        builder.setStatus(RpcStatusResult.success());
        responseObserver.onNext(builder.build());
        responseObserver.onCompleted();
    }


    /**
     * 根据 org_id 获取组织结构
     *
     * @param request:
     * @return
     * @author Linked <zhijian.lin@idiaoyan.com>
     * @date 2022/2/17 14:41
     */
    @Override
    public void listGroupsByOrgId(ListGroupsByOrgIdRequest request, StreamObserver<ListGroupsByOrgIdResponse> responseObserver) {
        ListGroupsByOrgIdResponse.Builder builder = ListGroupsByOrgIdResponse.newBuilder();
        GetGroupsByOrgIdOrPage page = UserGroupConverter.requestToGetGroupsByOrgIdOrPage(request);
        if (StringUtils.isBlank(page.getOrgId())) {
            String errMsg = String.format(CommonConstant.ERROR_MSG_FORMATTER, ErrorCodeEnum.PARAM_ERROR.getMsg(), "参数缺失");
            builder.setStatus(RpcStatusResult.error(errMsg));
            responseObserver.onNext(builder.build());
            responseObserver.onCompleted();
        }
        OrgStatusPageParam param = new OrgStatusPageParam();
        param.setOrgId(page.getOrgId());
        ServiceResult<Long> result = userGroupService.userGroupCountByOrgId(param);
        if (result.getData() >= 1000 && !page.isPageFlag()) {
            builder.setStatus(RpcStatusResult.error("数据量过大，建议分页"));
            responseObserver.onNext(builder.build());
            responseObserver.onCompleted();
        }
        List<Group> groups = new ArrayList<>();
        List<UserGroupDTO> groupList = userGroupService.listByOrgIdOrPage(page);
        for (UserGroupDTO userGroupDTO : groupList) {
            Group group = UserGroupConverter.userGroupDtoToGroup(userGroupDTO);
            groups.add(group);
        }
        if (page.isPageFlag()) {
            builder.setTotal(result.getData().intValue());
        }
        builder.addAllGroups(groups);
        builder.setStatus(RpcStatusResult.success());
        responseObserver.onNext(builder.build());
        responseObserver.onCompleted();

    }

    /**
     * 开放平台的层级更新
     *
     * @param request          grpc请求对象
     * @param responseObserver grpc响应对象
     * @author wangyunyun <yunyun.wang@idiaoyan.com>
     * @date 2022/2/17 13:47
     */
    @Override
    public void updateOpenGroupTree(UpdateOpenGroupTreeRequest request, StreamObserver<UpdateOpenGroupTreeResponse> responseObserver) {
        // 设置参数
        OpenGroupTreeParam param = new OpenGroupTreeParam();
        param.setLevels(UserGroupConverter.grpcsToSyncLevels(request.getLevelsList()));
        param.setGroups(UserGroupConverter.grpcsToSyncGroups(request.getGroupsList()));
        param.setOrgId(request.getOrgId());
        // 更新组织层级
        ServiceResult<String> serviceResult = null;
        try {
            serviceResult = userGroupBusinessService.updateOpenGroupTree(param);
        } catch (Throwable e) {
            log.error("开放平台的层级更新失败", e);
            serviceResult = ServiceResult.fail("系统异常");
        }

        UpdateOpenGroupTreeResponse.Builder builder = UpdateOpenGroupTreeResponse.newBuilder();
        if (serviceResult.isSuccess()) {
            // 操作成功
            builder.setStatus(RpcStatusResult.success());
            responseObserver.onNext(builder.build());
            responseObserver.onCompleted();

        } else {
            // 操作失败
            builder.setStatus(RpcStatusResult.error(serviceResult.getMsg()));
            responseObserver.onNext(builder.build());
            responseObserver.onCompleted();
        }
    }

    /**
     * 开放平台的层级异步更新
     *
     * @param request          grpc请求对象
     * @param responseObserver grpc响应对象
     * @author wangyunyun <yunyun.wang@idiaoyan.com>
     * @date 2022/2/17 13:47
     */
    @Override
    public void updateOpenGroupTreeByAsync(UpdateOpenGroupTreeByAsyncRequest request, StreamObserver<UpdateOpenGroupTreeByAsyncResponse> responseObserver) {
        // 设置参数
        OpenGroupTreeByAsyncParam param = UserGroupConverter.openGroupTreeByAsyncGrpc2Dto(request);
        // 更新组织层级
        ServiceResult<String> serviceResult = null;
        try {
            serviceResult = userGroupBusinessService.updateOpenGroupTreeByAsync(param);
        } catch (Throwable e) {
            log.error("开放平台的层级异步更新失败", e);
            serviceResult = ServiceResult.fail("系统异常");
        }

        // 设置返回值
        UpdateOpenGroupTreeByAsyncResponse.Builder builder = UpdateOpenGroupTreeByAsyncResponse.newBuilder();
        if (serviceResult.isSuccess()) {
            // 操作成功
            builder.setStatus(RpcStatusResult.success());
            builder.setTaskId(serviceResult.getData());
            responseObserver.onNext(builder.build());
            responseObserver.onCompleted();

        } else {
            // 操作失败
            builder.setStatus(RpcStatusResult.error(serviceResult.getMsg()));
            responseObserver.onNext(builder.build());
            responseObserver.onCompleted();
        }
    }

    /**
     * 获取组织和层级更新的任务
     *
     * @param request          grpc请求对象
     * @param responseObserver grpc响应对象
     * @author wangyunyun <yunyun.wang@idiaoyan.com>
     * @date 2022/6/7 14:26
     */
    @Override
    public void getUpdateOpenGroupTreeTask(GetUpdateOpenGroupTreeTaskRequest request, StreamObserver<GetUpdateOpenGroupTreeTaskResponse> responseObserver) {
        // 获取组织和层级更新的任务
        ServiceResult<UserGroupImportRecordDTO> serviceResult = null;
        try {
            serviceResult = userGroupImportRecordService.getUpdateOpenGroupTreeTask(request.getTaskId(), request.getOrgId());
        } catch (Throwable e) {
            log.error("获取组织和层级更新的任务失败", e);
            serviceResult = ServiceResult.fail("系统异常");
        }

        // 设置返回值
        GetUpdateOpenGroupTreeTaskResponse.Builder builder = GetUpdateOpenGroupTreeTaskResponse.newBuilder();
        if (serviceResult.isSuccess()) {
            // 操作成功
            UserGroupImportRecordDTO data = serviceResult.getData();
            builder.setStatus(RpcStatusResult.success());
            builder.setOrgId(data.getOrgId());
            builder.setTaskId(data.getImportId());
            builder.setTaskStatus(GroupTaskStatusEnum.GroupTaskStatus.forNumber(data.getStatus()));
            if (StringUtils.isNotBlank(data.getErrorMsg())) {
                builder.setError(data.getErrorMsg());
            }
        } else {
            // 操作失败
            builder.setStatus(RpcStatusResult.error(serviceResult.getMsg()));
        }
        responseObserver.onNext(builder.build());
        responseObserver.onCompleted();
    }

    /**
     * 根据组织id获取组织当前的用户数量
     *
     * @param request          grpc请求对象
     * @param responseObserver grpc响应对象
     * @author cuiqiongyu <qiongyu.cui@idiaoyan.cn>
     * @date 2022/06/30 11:34
     */
    @Override
    public void getUserNumByGroupId(GetUserNumByGroupIdRequest request, StreamObserver<GetUserNumByGroupIdResponse> responseObserver) {
        GetUserNumByGroupIdResponse.Builder builder = GetUserNumByGroupIdResponse.newBuilder();

        // 获取请求参数
        String groupId = request.getGroupId();
        String groupLevelId = request.getGroupLevelId();

        // 获取指定组织当前绑定的用户数量
        long count = userUserGroupService.countUserNumByGroupIdAndLevelId(groupId, groupLevelId);
        builder.setStatus(RpcStatusResult.success());
        builder.setNum((int) count);

        responseObserver.onNext(builder.build());
        responseObserver.onCompleted();
    }

    /**
     * 根据组织id列表查询所有的子组织+根据组织id列表和层级id查询对应的组织列表
     *
     * @param request          grpc请求对象
     * @param responseObserver grpc响应对象
     * @author cuiqiongyu <qiongyu.cui@idiaoyan.cn>
     * @date 2022/06/30 11:34
     */
    @Override
    public void listSubGroups(ListSubGroupsRequest request, StreamObserver<ListSubGroupsResponse> responseObserver) {
        ListSubGroupsResponse.Builder builder = ListSubGroupsResponse.newBuilder();

        // 获取请求参数
        List<String> groupIds = request.getIdsList();
        String levelId = request.getLevelId();
        if (CollectionUtils.isEmpty(groupIds)) {
            builder.setStatus(RpcStatusResult.error("组织id列表不能都为空"));
            responseObserver.onNext(builder.build());
            responseObserver.onCompleted();
            return;
        }

        // 根据组织id列表查询所有的子组织+根据组织id列表和层级id查询对应的组织列表
        ServiceResult<List<UserGroupDTO>> result = userGroupService.listSubGroups(groupIds, levelId);
        if (!result.isSuccess()) {
            builder.setStatus(RpcStatusResult.error(result.getMsg()));
        } else {
            builder.setStatus(RpcStatusResult.success());
            // 赋值组织列表信息
            builder.addAllGroups(UserGroupConverter.userGroupDtosToGroupBases(result.getData()));
        }

        responseObserver.onNext(builder.build());
        responseObserver.onCompleted();
    }


    /**
     * 根据groupId列表查找组织
     *
     * @param request
     * @param responseObserver
     * @return void
     * @author Linzhijian <zhijian.lin@idiaoyan.com>
     * @date 2022/07/13 19:57
     */
    @Override
    public void listGroupsByIds(ListGroupsByIdsRequest request, StreamObserver<ListGroupsByIdsResponse> responseObserver) {

        ListGroupsByIdsResponse.Builder builder = ListGroupsByIdsResponse.newBuilder();
        // 获取请求参数
        List<String> groupIds = request.getIdsList();
        if (CollectionUtils.isEmpty(groupIds)) {
            builder.setStatus(RpcStatusResult.error("组织id列表不能都为空"));
            responseObserver.onNext(builder.build());
            responseObserver.onCompleted();
            return;
        }

        // 通过id列表获取Group
        ServiceResult<List<UserGroupDTO>> result = userGroupService.listGroupsByIds(groupIds);
        if (!result.isSuccess()) {
            builder.setStatus(RpcStatusResult.error(result.getMsg()));
        } else {
            builder.setStatus(RpcStatusResult.success());
            // 赋值组织列表信息
            builder.addAllGroups(UserGroupConverter.userGroupDTOToResponse(result.getData()));
        }

        responseObserver.onNext(builder.build());
        responseObserver.onCompleted();
    }

    /**
     * 开放平台
     * rpc_apps_mysql/server/user/v1/user_server.py:350
     *
     * @param request
     * @param responseObserver
     * @return void
     * @author Linzhijian <zhijian.lin@idiaoyan.com>
     * @date 2022/07/13 20:42
     */
    @Override
    public void updateOpenGroupTreeV1(UpdateOpenGroupTreeV1Request request, StreamObserver<UpdateOpenGroupTreeV1Response> responseObserver) {
        UpdateOpenGroupTreeV1Response.Builder builder = UpdateOpenGroupTreeV1Response.newBuilder();
        // 设置参数
        OpenGroupTreeParam param = new OpenGroupTreeParam();
        param.setLevels(UserGroupConverter.grpcsToSyncLevelsV1(request.getLevelsList()));
        param.setGroups(UserGroupConverter.grpcsToSyncGroupsV1(request.getGroupsList()));
        param.setOrgId(request.getOrgId());
        if (StringUtils.isBlank(param.getOrgId())) {
            builder.setStatus(RpcStatusResult.error("org_id 缺失"));
            responseObserver.onNext(builder.build());
            responseObserver.onCompleted();
            return;
        }
        for (GroupLevelSyncParam level : param.getLevels()) {
            if (GroupLevelUtil.checkLevelNameInvalid(level.getName())) {
                builder.setStatus(RpcStatusResult.error("层级" + level.getName() + "格式错误"));
                responseObserver.onNext(builder.build());
                responseObserver.onCompleted();
                return;
            }
        }
        // 校验是否已加锁
        boolean lockFlag = groupLockUtil.getLockFlag(param.getOrgId());
        if (lockFlag) {
            builder.setStatus(RpcStatusResult.error(ResourceErrorCodeEnum.STATUS_CHANGED.getMsg()));
            responseObserver.onNext(builder.build());
            responseObserver.onCompleted();
            return;
        }
        try {
            // 加锁
            groupLockUtil.lock(param.getOrgId());
            ServiceResult<Boolean> serviceResult = userGroupBusinessService.updateOpenGroupTreeV1(param);
            if (serviceResult.isSuccess()) {
                builder.setStatus(RpcStatusResult.success());
            } else {
                builder.setStatus(RpcStatusResult.error(serviceResult.getMsg()));
            }
        } catch (GrpcCallFailedException e) {
            builder.setStatus(RpcStatusResult.error(e.getDesc()));
        } finally {
            // 解锁
            groupLockUtil.unlock(param.getOrgId());
        }
        responseObserver.onNext(builder.build());
        responseObserver.onCompleted();
    }

    /**
     * 查询层级列表
     *
     * @param request
     * @param responseObserver
     * @author wangyunyun <yunyun.wang@idiaoyan.com>
     * @date 2022/7/28 16:17
     */
    @Override
    public void listGroupLevels(ListGroupLevelsRequest request, StreamObserver<ListGroupLevelsResponse> responseObserver) {
        // 设置查询参数
        UserGroupLevelDTO groupLevelDTO = null;
        if (StringUtils.isNotBlank(request.getName())) {
            groupLevelDTO = new UserGroupLevelDTO();
            groupLevelDTO.setGroupLevelName(request.getName());
        }

        // 查询
        ServiceResult<List<UserGroupLevelDTO>> serviceResult = userGroupLevelService.listByOrgId(request.getOrgId(), groupLevelDTO);

        ListGroupLevelsResponse.Builder builder = ListGroupLevelsResponse.newBuilder();
        if (serviceResult.isSuccess()) {
            // 查询成功
            builder.setStatus(RpcStatusResult.success());

            if (CollectionUtils.isNotEmpty(serviceResult.getData())) {
                // 结果排序
                List<UserGroupLevelDTO> collect = serviceResult.getData().stream()
                        .sorted(Comparator.comparing(UserGroupLevelDTO::getLevelNum))
                        .collect(Collectors.toList());
                // 设置返回值
                builder.addAllLevels(UserGroupConverter.userGroupLevelDtosToGroupLevels(collect));
            }
        } else {
            // 查询失败
            builder.setStatus(RpcStatusResult.error(serviceResult.getMsg()));
        }

        responseObserver.onNext(builder.build());
        responseObserver.onCompleted();
    }

    @Override
    public void listSubGroupIdsByGroupId(ListSubGroupIdsByGroupIdRequest request,
                                         StreamObserver<ListSubGroupIdsByGroupIdResponse> responseObserver) {
        ListSubGroupIdsByGroupIdResponse.Builder builder = ListSubGroupIdsByGroupIdResponse.newBuilder();
        String msg = "";
        if (!ObjectId.isValid(request.getOrgId())) {
            msg = "机构id格式不对";
        }

        if (!ObjectId.isValid(request.getGroupId())) {
            msg = "组织id格式不对";
        }

        int page = request.getPage().getPage();
        int size = request.getPage().getSize();
        if (page < 1) {
            msg = "页数不能小于1";
        }
        if (size > 10000) {
            msg = "每页大小不能超过10000";
        }

        if (StringUtils.isNotEmpty(msg)) {
            builder.setStatus(RpcStatusResult.error(msg));
            responseObserver.onNext(builder.build());
            responseObserver.onCompleted();
            return;
        }

        // 查询
        ServiceResult<PageResponseDTO<String>> serviceResult = userGroupService
                .listSubGroupIdsByGroupId(request.getOrgId(), request.getGroupId(), page, size);
        if (serviceResult.isSuccess()) {
            // 查询成功
            builder.setStatus(RpcStatusResult.success());
            builder.setTotal(serviceResult.getData().getTotal().intValue());
            // 设置返回值
            builder.addAllGroupIds(serviceResult.getData().getRows());
        } else {
            // 查询失败
            builder.setStatus(RpcStatusResult.error(serviceResult.getMsg()));
        }

        responseObserver.onNext(builder.build());
        responseObserver.onCompleted();
    }

    /**
     * id正则匹配校验
     *
     * @param id
     * @return java.util.Collection<java.lang.String>
     * @author panyun <yun.pan@idiaoyan.com>
     * @date 2022/2/7 16:16
     */
    private String validateId(String id) {
        boolean matches = id.matches(RegTypes.OBJECT_ID);
        if (!matches) {
            return "id格式不正确";
        }
        return null;
    }

}
